﻿using System;
using System.DirectoryServices;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Microsoft.NetMicroFramework.Tools.MFDeployTool.Engine;

namespace NDDeploy
{
    public partial class Form1 : Form
    {
        private MFDeploy _mfDeploy;
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            buttonDeploy.Enabled = false;
            _mfDeploy = new MFDeploy();
            timer1.Interval = 2000;
            timer1.Enabled = true;
            timer1.Start();
            timer1.Tick += timer1_Tick;

        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _mfDeploy.Dispose();
            timer1.Stop();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            var devicePorts = _mfDeploy.EnumPorts(TransportType.USB);
            if (devicePorts.Count != 0)
            {
                foreach (var mfPortDefinition in devicePorts)
                {
                    comboBoxTarget.Items.Add(mfPortDefinition);
                }
                timer1.Stop();
                comboBoxTarget.SelectedIndex = 0;
                buttonDeploy.Enabled = true;
            }
        }

        private void buttonDeploy_Click(object sender, EventArgs e)
        {
            textBoxStatus.Text = "";
            try
            {
                var port = (MFPortDefinition)comboBoxTarget.SelectedItem;
                AddLog("Connecting To device.");

                var device = _mfDeploy.Connect(port);
                AddLog("Pinging device.");
                PingConnectionType p = device.Ping();
                string currentDir = Environment.CurrentDirectory;
                var hexFile = currentDir + @"\setup.hex";
                uint ep = 0;
                if (device.ConnectToTinyBooter())
                {
                    AddLog("Connected To TinyBooter.");
                    device.Erase(EraseOptions.Deployment);
                    AddLog("Erasing existing deployment.");

                    if (device.Deploy(hexFile, null, ref ep))
                    {
                        AddLog("Deployment successful.");
                        device.Reboot(true);
                    }
                    else
                    {
                        AddLog("Deployment failed!");
                    }
                }
            }
            catch (Exception)
            {
                AddLog("Deployment failed!");
            }

        }

        private void AddLog(string text)
        {
            textBoxStatus.Text = text;
        }

        private void buttonMicroSd_Click(object sender, EventArgs e)
        {
            folderBrowserDialog1.Description = "Select micro SD card";
            folderBrowserDialog1.ShowNewFolderButton = false;
            folderBrowserDialog1.RootFolder = Environment.SpecialFolder.MyComputer;
            if (folderBrowserDialog1.ShowDialog(this) == DialogResult.OK)
            {
                if (IsDirectoryEmpty(folderBrowserDialog1.SelectedPath))
                {
                    var target = new DirectoryInfo(folderBrowserDialog1.SelectedPath);
                    CopyFilesRecursively(new DirectoryInfo(Environment.CurrentDirectory + @"\MicroSD"), target);
                    AddLog("Files have been copied to your SD card");
                }
                else
                {
                    AddLog("This SD card is not empty, please format the card.");
                }
            }
        }

        public static void CopyFilesRecursively(DirectoryInfo source, DirectoryInfo target)
        {
            foreach (DirectoryInfo dir in source.GetDirectories())
                CopyFilesRecursively(dir, target.CreateSubdirectory(dir.Name));
            foreach (FileInfo file in source.GetFiles())
                file.CopyTo(Path.Combine(target.FullName, file.Name));

        }

        public bool IsDirectoryEmpty(string path)
        {
            return !Directory.EnumerateFileSystemEntries(path).Any();
        }
    }
}
